package com.weim.weim.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

/**
 * @author leigx
 * @description: aliyun oss 上传
 * @title: AliOssUploadUtil
 * @projectName bocc
 * @date 2022/4/14 19:43
 */
@Slf4j
public class AliOssUploadUtil {

    @Value("${blob.prefix}")
    private String prefix;

    @Value("${alibaba.cloud.endPoint}")
    private String endpoint;

    @Value("${alibaba.cloud.access-key}")
    private String accessKey;

    @Value("${alibaba.cloud.secret-key}")
    private String secretKey;

    @Value("${alibaba.cloud.bucketName}")
    private String bucketName;
    @Value("${alibaba.cloud.application}")
    private String application;
    private OSS client;

    private OSSClientBuilder ossClientBuilder;

    public OSS getOSSClient(){
        if (client == null) {
            client = getOSSClientBuilder().build(endpoint, accessKey, secretKey);
            log.info("getClient");
        }
        return  client;
    }

    public OSSClientBuilder getOSSClientBuilder(){
        if(ossClientBuilder == null){
            ossClientBuilder = new OSSClientBuilder();
            log.info("getOSSClientBuilder");
        }
        return ossClientBuilder;
    }


    /**
     * 字节流上传
     * @param multipartFile
     * @return void
     * @author leigx
     * @date 2022/4/15 15:41
     */
    public void uploadStream(MultipartFile multipartFile, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        ByteArrayInputStream inputStream = null;
        try {
            inputStream =  new ByteArrayInputStream(multipartFile.getBytes());
            // 创建PutObject请求。
            ossClient.putObject(bucketName, getPrefix()+objectName,  inputStream);
        } catch(Exception e){
            log.error("文件流上传阿里云异常：", e);
        } finally {
            if (inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("关闭流异常",e);
                }
            }
        }
    }
    private String getPrefix(){
        return  application + "/";
    }
    /**
     * 字节流上传
     * @param bytes
     * @return void
     * @author leigx
     * @date 2022/4/15 15:41
     */
    public void uploadStream(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        ByteArrayInputStream inputStream =  new ByteArrayInputStream(bytes);
        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, getPrefix()+objectName,  inputStream);
        } catch(Exception e){
            log.error("文件流上传阿里云异常：", e);
        } finally {
            if (inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("关闭流异常",e);
                }
            }
        }
    }

    /**
     * 字节流上传
     * @param bytes
     * @return void
     * @author leigx
     * @date 2022/4/15 15:41
     */
    public String uploadStreamData(byte[] bytes, String objectName, String fileName) {
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        ByteArrayInputStream inputStream =  new ByteArrayInputStream(bytes);
        try {
            // 创建PutObject请求。
            ObjectMetadata meta = new ObjectMetadata();
            String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(bytes));
            meta.setContentMD5(md5);
            meta.setContentType("text/plain");
            meta.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
            // 设置内容被下载时的编码格式。
            meta.setContentEncoding("utf-8");
            String firstKey = getPrefix() + objectName;
            ossClient.putObject(bucketName, firstKey,  inputStream, meta);
            // 解析结果
            return firstKey;
        } catch(Exception e){
            log.error("文件流上传阿里云异常：", e);
        } finally {
            if (inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error("关闭流异常",e);
                }
            }
        }
        return null;
    }

    /**
     * 下载
     *
     * @param nameUrl nameUrl
     * @return {@link byte[] }
     */
    public byte[] downloadStream(String nameUrl) {
        if (StringUtils.isBlank(nameUrl)) {
            return null;
        }
        // 创建OSSClient实例。
        OSS ossClient = getOSSClient();
        String objectName = StringUtils.replaceOnce(nameUrl, prefix + "/", StringUtils.EMPTY);
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName);
        try {
            OSSObject ossObject = ossClient.getObject(getObjectRequest);
            try (InputStream objectContent = ossObject.getObjectContent()) {
                return IOUtils.toByteArray(objectContent);
            }
        } catch (Exception e) {
            log.error("文件流下载阿里云异常：", e);
        }
        return null;
    }

}
